package com.qfedu.edu.exceptionbusinesshandlerservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qfedu.edu.bo.QueueMessage;
import com.qfedu.edu.constance.RabbitMQConstance;
import com.qfedu.edu.exception.BusinessException;
import com.qfedu.edu.manager.RabbitMQManager;
import com.qfedu.edu.po.Exception;
import com.qfedu.edu.exceptionbusinesshandlerservice.mapper.ExceptionMapper;
import com.qfedu.edu.exceptionbusinesshandlerservice.service.ExceptionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qfedu.edu.result.ResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xiaobobo
 * @since 2024-11-18
 */
@Service
@Slf4j
public class ExceptionServiceImpl extends ServiceImpl<ExceptionMapper, Exception> implements ExceptionService {

    @Autowired
    private ExceptionMapper exceptionMapper;

    @Autowired
    private RabbitMQManager rabbitMQManager;

    @Override
    public void handlerExceptionBusiness(String msg) {
        //这里只需要正常入库就业可以了...
        try {
            QueueMessage queueMessage = JSON.parseObject(msg, QueueMessage.class);
            //执行到这里 说明这个消息是有数据的...
            Integer type = queueMessage.getType();
            //封装消息
            Exception exception = new Exception();
            exception.setExceptionType(type);
            exception.setExceptionMsg(msg);
            exceptionMapper.insert(exception);
        }catch (java.lang.Exception err){
            //失败了说明这个消息可能是MySQL向ES中同步的信息
            //这个消息是有具体的这个
            //下面就是要将这个数据封装成对象去使用...
            //首先将这个数据弄成JSONObject对象
            JSONObject jsonObject = JSON.parseObject(msg);
            //接下就可以获取当前操作的是哪一张表  以及 这个操作的类型是啥
            String tableName = jsonObject.getString("table");
            String type = jsonObject.getString("type");
            if(!StringUtils.isEmpty(tableName)&&!StringUtils.isEmpty(type)){
                //说明这个消息是：MySQL向ES中的同步信息
                //那么就封装这个异常对象
                Exception exception = new Exception();
                exception.setExceptionMsg(msg);
                //如果存储到MySQL中的数据 没有这个type那么就认为这个消息是MySQL向ES中的同步消息
                //接下来将数据放到数据库
                exceptionMapper.insert(exception);
                return;
            }
            //如果执行到这里 说明这个消息不是MySQL向ES中的同步消息... 那么这个时候 就抛出异常
            throw err;
        }

    }

    @Override
    public IPage<Exception> listByPage(Integer currentPage, Integer pageSize) {
        if(null==currentPage||null==pageSize){
             throw new BusinessException(ResponseCode.PARAM_EXCEPTION);
        }
        //执行到这里 说明无误
        IPage<Exception> exceptionIPage=new Page<>();
        exceptionIPage.setCurrent(currentPage);
        exceptionIPage.setSize(pageSize);
        //最后进行查询
        IPage<Exception> exceptionIPage1 = exceptionMapper.selectPage(exceptionIPage, null);
        return exceptionIPage1;
    }

    @Override
    public void retryBusiness(Integer exceptionId) throws UnsupportedEncodingException {
        if(null==exceptionId){
           throw new BusinessException(ResponseCode.PARAM_EXCEPTION);
        }
        //执行到这里 参数有id
        //那么这个时候 我们就需要通过id去查询这个数据
        Exception exception = exceptionMapper.selectById(exceptionId);
        //查询出来之后取出这个消息
        String exceptionMsg = exception.getExceptionMsg();
        //那么这个消息 我们就要判断这个消息是呢种类型的消息
        try {
            QueueMessage queueMessage = JSON.parseObject(exceptionMsg, QueueMessage.class);
            //执行到这里 说明转换是成功的...
            //那么取出这个队列的名字
            String queueName = queueMessage.getQueueName();
            //然后发送消息到队列中去重试
            rabbitMQManager.sendWork(queueName,exceptionMsg);
            log.info("手动发送消息到队列中成功....");
        }catch (java.lang.Exception err){
            //执行到这里 这个消息是 MySQL向ES中的这个同步的消息
            //失败了说明这个消息可能是MySQL向ES中同步的信息
            //这个消息是有具体的这个
            //下面就是要将这个数据封装成对象去使用...
            //首先将这个数据弄成JSONObject对象
            JSONObject jsonObject = JSON.parseObject(exceptionMsg);
            //接下就可以获取当前操作的是哪一张表  以及 这个操作的类型是啥
            String tableName = jsonObject.getString("table");
            String type = jsonObject.getString("type");
            if(!StringUtils.isEmpty(tableName)||!StringUtils.isEmpty(type)){
                //那么说明是MySQL向ES中发送的这个同步的消息
                //那么从新去进行同步...
                rabbitMQManager.sendWork(RabbitMQConstance.getMysqlMqName(),exceptionMsg);
                log.info("消息手动发送到队列成功....");
                return;
            }
            throw err;
        }
    }
}
